/* Copyright (c) 2015,2016 Lucky Byte, Inc.
 */
package com.lucky_byte.pay.sched;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.lucky_byte.pay.jar.Jdbc;
import com.lucky_byte.pay.jar.Runtime;

public abstract class AbstractJob implements Job
{
	private static final Logger logger = LogManager.getLogger();

	protected int serial;
	protected String name;
	protected String script;
	protected String params;

	/**
	 * 任务序号
	 */
	public void setSerial(int serial) {
		this.serial = serial;
	}

	/**
	 * 任务名称
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 脚本文件
	 */
	public void setScript(String script) {
		this.script = script;
	}

	/**
	 * 附加参数
	 */
	public void setParams(String params) {
		this.params = params;
	}

	/**
	 * 替换参数中的特殊变量
	 */
	private List<String> normalizeParams() {
		if (params == null || params.trim().isEmpty()) {
			return null;
		}
		Map<String, String> variables = new HashMap<>();

		Calendar calendar = Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + 1;
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		int hour = calendar.get(Calendar.HOUR);
		int hour24 = calendar.get(Calendar.HOUR_OF_DAY);
		int minute = calendar.get(Calendar.MINUTE);
		int second = calendar.get(Calendar.SECOND);

		variables.put("@YYYY@", Integer.toString(year));
		variables.put("@YY@", Integer.toString(year % 100));
		variables.put("@MM@", String.format("%02d", month));
		variables.put("@M@", Integer.toString(month));
		variables.put("@DD@", String.format("%02d", day));
		variables.put("@D@", Integer.toString(day));
		variables.put("@HH@", String.format("%02d", hour24));
		variables.put("@H@", Integer.toString(hour24));
		variables.put("@hh@", String.format("%02d", hour));
		variables.put("@h@", Integer.toString(hour));
		variables.put("@mm@", String.format("%02d", minute));
		variables.put("@m@", Integer.toString(minute));
		variables.put("@ss@", String.format("%02d", second));
		variables.put("@s@", Integer.toString(second));

		variables.put("@DATE@", Integer.toString(year) + "-" +
				String.format("%02d", month) + "-" +
				String.format("%02d", day));
		variables.put("@date@", Integer.toString(year) + "-" +
				Integer.toString(month) + "-" + Integer.toString(day));

		variables.put("@TIME@", String.format("%02d", hour24) + ":" +
				String.format("%02d", minute) + ":" +
				String.format("%02d", second));
		variables.put("@time@", String.format("%02d", hour) + ":" +
				String.format("%02d", minute) + ":" +
				String.format("%02d", second));

		String normalize = params;
		for (String key : variables.keySet()) {
			normalize = normalize.replaceAll(key, variables.get(key));
		}
		String[] arr = normalize.split("\\s");

		// 去除空白的项
		List<String> ret = new ArrayList<>();
		for (String str : arr) {
			if (str.trim().length() > 0) {
				ret.add(str);
			}
		}
		return ret;
	}

	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		File file = Runtime.fileFor("/lua/sched/" + script);
		if (file == null) {
			logger.error("找不到任务[{}]关联的脚本文件[{}].", name, script);
			return;
		}
		this.doJob(file, this.normalizeParams(), context);
		try {
			List<Object> params = new ArrayList<>();
			params.add(this.serial);
			Jdbc.update("update pay_sched set sched_cnt = sched_cnt + 1,"
					+ "last_sched = CURRENT_TIMESTAMP where serial = ?",
					params);
		} catch (SQLException e) {
			logger.error("更新任务调度表错误[{}][{}].", e.getMessage(),
					e.getClass().getSimpleName());
		}
	}

	abstract protected void doJob(File script, List<String> params,
			JobExecutionContext context) throws JobExecutionException;
}
